<template>
    <el-space class="theme-control" direction="vertical">
        <!-- type -->
        <el-select v-model="type" @change="changeType">
            <el-option v-for="item in types" :key="item" :value="item">{{
                item
            }}</el-option>
        </el-select>

        <!-- color -->
        <el-select v-model="theme" @change="changeColor">
            <el-option v-for="item in themeTypes" :key="item" :value="item">{{
                item
            }}</el-option>
        </el-select>
    </el-space>
</template>

<script setup lang="ts">
import { ref, onMounted } from "vue";
import storeTheme from "../store/theme";
import type { typeThemeMode, typeColor } from "../types/theme.ts";

/* store */
const store = storeTheme();

/* data */
// 主题类型
const types = ["light", "dark"];
const type = ref<typeThemeMode>("light");
// 主题颜色
const themeTypes = ["default", "purple", "orange", "cyan", "pink"];
const theme = ref<typeColor>("default");
// 系统默认主题
const mediaQueryList: MediaQueryList = window.matchMedia(
    "(prefers-color-scheme: dark)"
);

/* mounted */
onMounted(() => {
    mediaThemeEvent(mediaQueryList.matches); // 初始化主题
    watchMediaTheme(); // 监视浏览器主题
});

// 更改 主题 类型
const changeType = (value: typeThemeMode) => {
    setRootThemeMode(value);
};
// 更改 主题 颜色
const changeColor = (): void => {
    setRootClass();
};
// 设置 root 类名
const setRootClass = () => {
    const color = (theme.value === "default" ? "" : theme.value) as typeColor;
    document.documentElement.setAttribute("theme-color", color);

    store.setColor(color);
};

// 过度动画
const setRootThemeMode = (mode: typeThemeMode): void => {
    const tran = document.startViewTransition(() => {
        setModeClass(mode);
    });

    tran.ready.then(() => {
        transformBackground();
        // transformText();
    });
};
// 设置 主题模式 类名
const setModeClass = (mode: typeThemeMode) => {
    document.documentElement.setAttribute("theme-mode", mode);

    if (mode === "dark") {
        document.documentElement.classList.add("dark");
    } else {
        document.documentElement.classList.remove("dark");
    }

    store.setMode(mode);
};
// 背景过度
const transformBackground = () => {
    const target = document.querySelector(".theme-control") as HTMLDivElement;
    const { x, y } = target.getBoundingClientRect();
    const r = Math.hypot(
        Math.max(x, innerWidth - x),
        Math.max(y, innerHeight - y)
    );
    let path: Keyframe[] = [
        {
            clipPath: `circle(0px at ${x}px ${y}px)`,
        },
        {
            clipPath: `circle(${r}px at ${x}px ${y}px)`,
        },
    ];

    const isDark = document.documentElement.classList.contains("dark");

    document.documentElement.animate(isDark ? path.reverse() : path, {
        duration: 500,
        pseudoElement: isDark
            ? "::view-transition-old(root)"
            : "::view-transition-new(root)",
    });
};

/* tool */
// 获取浏览器默认主题模式 深色、浅色
const watchMediaTheme = () => {
    mediaQueryList.addEventListener("change", (event: MediaQueryListEvent) => {
        mediaThemeEvent(event.matches);
    });
};
// 更改 type值 并且更换主题模式类名
const mediaThemeEvent = (matches: boolean): any => {
    const mode: typeThemeMode = matches ? "dark" : "light";
    type.value = mode;
    setModeClass(mode);
};
// 浏览器
</script>

<style lang="scss" scoped>
.theme-control {
    position: fixed;
    top: 10px;
    left: 10px;
    .el-select {
        width: 160px;
    }
}
</style>
